/*
 *  viewManager.js
 *  This file has these main responsibilities:
 *  1. Updates the display with new information provided by the model in
 *  response to user clicks 
 *
 *  @author Tanya L. Crenshaw, John Olennikov
 */

define(['jquery', 'dataManager'], function($, dm) {

    var marker;
    // Append vars that store jQuery selectors with a '$'
    // to show that they are jQuery selectors
    var $prevMarker;
    var $prevContain;

    /*
     *
     * The following functions extract html data from the
     * html data forms on the page
     *
     */

    /*
     * getCounselor()
     *
     * This function extracts the select counselor in the 
     * counselor's dropdown menu
     *
     * @return value of counselor select element
     */
    var getCounselor = function() 
    {
        return $("#drop-down option:selected").val();
    };
    
    /*
     * getAppStatus()
     *
     * This function extracts the application status filter selection
     *
     * @return value of application status radio button
     */
    var getAppStatus = function() 
    {
        return $("input[name=admission-status]:checked").val();
    };

    /*
     * getDataView()
     * 
     * This function extracts the data table's filter view
     * 
     * @return value of application status radio button
     */
    var getDataView = function() 
    {
        return $("input[name=data-view-type]:checked").val();
    };

    /*
     * getSelectedSchool()
     * 
     * This function extracts the element which is currently
     * selected in the data table and returns it as a
     * jQuery selector
     * 
     * @return currently selected data table jQuery element
     */
    var getSelectedSchool = function() 
    {
        return $( ".data-box-selected" );
    }; 



    /*
     * getDataContainer()
     * 
     * This function extracts dataContainer element 
     * that is used to textually display map data
     *
     * @return jQuery element referencing the data table
     */ 
    var getDataContainer = function() 
    {
        return $("#right-info-data");
    };
    

    /*
     *
     * The following functions manipulate html elements
     * on the page by creating, removing, or changing
     * html values/elements on the page
     *
     */ 

    /*
     * createDataContain(data)
     * 
     * This function creates the html container to hold a
     * single school's information in the data table
     * 
     * @param data the information to populate appropriate fields
     * @return html string representation of school information
     */
    var createDataContain = function(data) 
    {
        var elem = "<div id=\"school-info-" + data[0] + "\" class=\"data-box-contain\" " + 
                   " data-latlng=\"" + data[4] + "#" + data[5] + "\">"+
                   "<p><span>School Name:</span> " + data[1] + " </p>" +
                   "<p><span>Number of Apps:</span> " + data[2] +  " </p>" +
                   "<p><span>Location:</span> " + data[6] + ", " + data[7] + " </p></div>";

        return elem;
    };


    /*
     * updateMap(data)
     * 
     * This function zooms in/out to display all data points on the map
     * 
     * @param data the location points to show on map
     */
    var updateMap = function(map,data) 
    {
        var bounds = new google.maps.LatLngBounds();

        for (ix = 0; ix < data.length; ++ix) 
        {
            bounds.extend(new google.maps.LatLng(data[ix][4],data[ix][5]));
        }
        map.fitBounds(bounds);
    };

    /*
     * updateDisplay(data)
     * 
     * This function update the data table with map information
     * 
     * @param data JS object to format and display in table
     */
    var updateDisplay = function(data) 
    {
        var $contain = getDataContainer();
        var $select = getSelectedSchool();

        console.log("Clearing data table.");
        $contain.empty();
        
        console.log("Updating values.");
        for(var ix = 0; ix < data.length; ++ix) 
        {
            $contain.append(createDataContain(data[ix]));
        }

        
        // Maintain selected option
        if ($select != undefined) {
            var $toSelect = $( "#" + $select.attr("id"));

            if ($toSelect.length > 0) 
            {
                highlightSchool($toSelect);
            }
        }
    };

    /*
     * createMarker(map, code, coord)
     * 
     * This function creates a marker, rather than a dot, on the map
     * in response to map or table entry selection.
     * 
     * @param map A copy of the map layer
     * @param code CEEB code for the selected high school
     * @param coord Google Maps coordinate location for the selected high school
     */
    var createMarker = function(map,code,coord) 
    {
        marker = new google.maps.Marker
        ({
            map: map,
            position: coord,
            suppressInfoWindows: true,
        });
        google.maps.event.addListener(marker, 'click', function(event) 
        {
            this.setMap(null);
            $( "#school-info-" + code ).removeClass("data-box-selected");
        });

    };

    /*
     * updateSelection(map, code, LatLng)
     * 
     * This function creates a highlighted table entry in the data box in response
     * to map or table entry selection.  
     * 
     * @param map A copy of the map layer
     * @param code CEEB code for the selected high school
     * @param LatLng Google Maps location for the selected high school
     */
    var updateSelection = function(map,code,latLng) 
    {
        var $contain = $( "#school-info-" + code );

        if (!$contain.hasClass("data-box-selected"))
        {
            if (!($prevContain === undefined)) 
            {
                $prevMarker.setMap(null);
                // Because the content is refreshed, even though the id might exist,
                // jQuery no longer has a handle on it (since that element was deleted).
                // Therefore, remove it after you reassign a handle to that id
                unhighlightSchool($("#"+$prevContain.attr("id")));

            }
            var latLng = new google.maps.LatLng(latLng[0], latLng[1]);
            createMarker(map, code, latLng);
            map.setCenter(latLng);
            highlightSchool($contain);
        }
        else
        {
            $prevMarker.setMap(null);
            unhighlightSchool($prevContain);
        }

        $prevContain = $contain;
        $prevMarker = marker;

        // Scroll to selected div
        scrollToChild($contain);
    };

    /*
     * updateView(map, SchoolData)
     * 
     * This function changes the view in response to user selection, or deslection, of
     * a map marker or table entry.  
     * 
     * @param map A copy of the map layer
     * @param schoolData CEEB, coordinates, etc. of selected or deslected school
     */
    var updateView = function(map,schoolData) 
    {
        $select = getSelectedSchool();
        updateMap(map,schoolData);
        updateDisplay(schoolData);

        // Make sure selected element still exists
        $toSelect = $( "#" + $select.attr("id") );

        if ($toSelect.length > 0) {
            scrollToChild($toSelect);
        } else if ($prevContain != undefined) {
            $prevMarker.setMap(null);
            unhighlightSchool($prevContain);
        }
    }

    /*
     * highlightSchool($school)
     * 
     * This function "calls" the CSS Style to highlight the selected school in the data box.  
     * 
     * @param $school Reference to specific school to be highlighted 
     */
    var highlightSchool = function($school)
    {
        $school.addClass("data-box-selected");
    }
    
    /*
     * unhighlightSchool($school)
     * 
     * This function "calls" the CSS Style to remove highlight from the selected school in the data box.  
     * 
     * @param $school Reference to specific school to be uhighlighted 
     */
    var unhighlightSchool = function($school)
    {
        $school.removeClass("data-box-selected");
    }
    
    /*
     * highlightSchool($elem)
     * 
     * This function reacts to the user selecting a dot on the map by scrolling to that
     * school in the data box.   
     * 
     * @param $elem Reference to specific school to be scrolled to in the data box
     */
    var scrollToChild = function($elem) 
    {
        //body.animate({scrollTop:0}, '500', 'swing', function() { 
        //    alert("Finished animating");
        //});

        var $dv = $elem.parent();
        var pos = $dv.scrollTop() + ($elem.position().top - $dv.position().top) - 
                ($dv.height()/2) + $elem.height()*3;

        $dv.animate({scrollTop: pos},'200', 'swing', function() {
        });

        //$dv.scrollTop($dv.scrollTop() + ($elem.position().top - $dv.position().top) - 
        //        ($dv.height()/2) + $elem.height()*3);
    }

    // Any functions defined in this return statement are considered public
    // functions by RequireJS, and accessible through the namespace that
    // is attached to this module when loaded in other files.
    return {
        getCounselor : getCounselor,
        getAppStatus : getAppStatus,
        getDataView : getDataView,
        getSelectedSchool : getSelectedSchool,
        updateView : updateView,
        updateSelection : updateSelection,
    };

});
